package com.zjpavt.client.udp.artnet.controlPanel;


import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

/**
 *
 * suite在线控制器
 * @author zyc
 */
@Slf4j
public class SuiteOnlineController extends AbstractArtNetController {
    /**
     * suite中的第几个字节代表当前所在域 从0开始
     * EXTERNSTART = subnet + universe
     */
    private static final int EXTERNSTART_BYTE_INDEX = 14;


    /**
     * 用于统计收到的UDP数量
     */
    private AtomicInteger receiveCount = new AtomicInteger(0);
    /**
     * 回路变更锁
     */
    private ReentrantLock channelChangeLock = new ReentrantLock();

    /**
     * @param externstart 所在域 0-255
     */
//    public SuiteOnlineController(int externstart) {
//        super(externstart);
//    }

    public SuiteOnlineController(int externstart,int beginChannelIndex, int channelLength) {
        super(externstart);
        setBeginChannelIndex(beginChannelIndex);
        setChannelLength(channelLength);
    }

    public SuiteOnlineController(int externstart,int beginChannelIndex, int channelLength,int speed) {
        this(externstart,beginChannelIndex,channelLength);
        this.speed = speed;
    }

    /**
     * 是否为符合期望的数据包
     * 为当前域
     * @param datagramPacket
     * @return
     */
    @Override
    protected boolean isValid(byte[] datagramPacket) {
        if (datagramPacket.length != ART_NET_PACKET_LENGTH || datagramPacket[EXTERNSTART_BYTE_INDEX] != externstart) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 筛选是否为需要的数据包
     * 截取出需要的数据
     *
     * 例如截取出第三个域的500-511通道 作为控制当前设备回路状态的通道
     * @param data
     * @return
     */
    @Override
    public byte[] getControlData(byte[] data) {
        if (!isValid(data)) {
            return null;
        }
        if (receiveCount.incrementAndGet() < speed) {
            return null;
        }
//      当开始解析数据时 统计归0
        receiveCount.set(0);
//            含beginIndex 以及 endIndex
        int beginIndex = beginChannelIndex + ART_NET_CONTROL_BYTE_LENGTH;
        int endIndex = beginIndex + channelLength - 1 ;
        byte[] commandBytes = new byte[channelLength];
        for (int i = beginIndex; i <= endIndex; i++) {
            commandBytes[i - beginIndex] = data[i];
        }
        StringBuilder controlInformation = new StringBuilder();
        controlInformation.append("control byte: ");
        for (int i = 0; i < ART_NET_CONTROL_BYTE_LENGTH; i++) {
            controlInformation
            .append(String.valueOf(data[i]))
            .append(" ");
        }
        controlInformation.append("commands: ");
        for (byte b : commandBytes) {
            controlInformation.append(String.valueOf(b)).append(" ");
        }
        log.debug(controlInformation.toString());
        return commandBytes;
    }
}
